﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SMA = System.Management.Automation;

namespace RSPowershell
{

    [System.Management.Automation.Cmdlet("Render", "RSReport")]
    public class Render_RSReport : SMA.Cmdlet
    {
        [SMA.Parameter(Mandatory = true, Position = 0)]
        public string Path;

        [SMA.Parameter(Mandatory = true, Position = 1)]
        public string Format;

        [SMA.Parameter(Mandatory = true, Position = 2)]
        public string OutputFilename;

        [SMA.Parameter(Mandatory = false)]
        public DeviceInfo DeviceInfo;

        protected override void ProcessRecord()
        {
            var rep_svc = this.ConnectToReportingService();
            var rep_exec_svc = this.ConnectToReportExecutionService();

            ReportExecutionService.Warning[] rendered_warnings = null;
            string[] rendered_stream_ids = null;

            var exec_info = new ReportExecutionService.ExecutionInfo();
            var exec_header = new ReportExecutionService.ExecutionHeader();

            rep_exec_svc.ExecutionHeaderValue = exec_header;
            string historyid = null;

            this.WriteVerbose("Loading Report");
            exec_info = rep_exec_svc.LoadReport(this.Path, historyid);

            //rs2.SetExecutionParameters(parameters, "en-us");

            var session_id = rep_exec_svc.ExecutionHeaderValue.ExecutionID;
            this.WriteVerbose("SessionID: {0}", rep_exec_svc.ExecutionHeaderValue.ExecutionID);

            byte[] rendered_bytes = null;

            try
            {

                var devinfo = this.DeviceInfo ?? new DeviceInfo();
                //devinfo.Toolbar = false;

                var devinfo_xmldoc = devinfo.ToXML();
                string device_info = devinfo_xmldoc.ToString();

                this.WriteVerbose("DeviceInfo: {0}", device_info);

                this.WriteVerbose("Starting Render");

                string rendered_encoding;
                string rendered_mimetype;
                string rendered_extension;

                rendered_bytes = rep_exec_svc.Render(
                    this.Format,
                    device_info,
                    out rendered_extension,
                    out rendered_encoding,
                    out rendered_mimetype,
                    out rendered_warnings, 
                    out rendered_stream_ids);

                this.WriteVerbose("Ending Render");
                
                // Handle Warnings
                if (rendered_warnings!= null)
                {
                    this.WriteVerbose("Number of warnings : {0}", rendered_warnings.Length);
                    foreach (var w in rendered_warnings)
                    {
                        this.WriteVerbose("Warning: {0}", w.Code);
                        this.WriteVerbose(" Message: {0}", w.Message);
                        this.WriteVerbose(" Severity: {0}", w.Severity);
                        this.WriteVerbose(" ObjectName: {0}", w.ObjectName);
                        this.WriteVerbose(" ObjectType: {0}", w.ObjectType);
                    }
                }


                // Handle Streams
                if (rendered_stream_ids!=null)
                {
                    this.WriteVerbose("Number of streams ids: {0}", rendered_stream_ids.Length);
                    foreach (var sid in rendered_stream_ids)
                    {
                        this.WriteVerbose("streams id: {0}", sid);
                    }
                }

                // Handle Execution Info
                exec_info = rep_exec_svc.GetExecutionInfo();
                this.WriteVerbose("Execution date and time: {0}", exec_info.ExecutionDateTime);
            }
            catch (System.Web.Services.Protocols.SoapException err)
            {
                this.WriteVerbose("Caught SoapException");
                this.WriteVerbose("Message: {0}", err.Message);
                throw err;
            }

            this.WriteVerbose("Writing output file");
            this.WriteVerbose("Size of result: {0}", rendered_bytes.Length);
            var stream = System.IO.File.Create(this.OutputFilename, rendered_bytes.Length);
            stream.Write(rendered_bytes, 0, rendered_bytes.Length);
            stream.Close();
            this.WriteVerbose("Finsihed writing output file");

        }
    }
}
